package model;


import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Set;
import search.SearchTuple;
import RMI.ContactService;
import RMI.RemoteInt;
/**
 * this cladd contains all the logic behind the GUI 
 * @author ran & barak
 *
 */
public class Model {
	private RemoteInt remoteInt;
	//static member for singelton pattern
	private static Model model=new Model();
	
	/**
	 * @return Simulation instance 
	 */
	public static Model getModel(){
		return model;
	}
	/*
	 * constructor of the class
	 */
	private Model(){
		remoteInt=null;
	
	}
	public void openRemotInt(){
		ContactService con=new ContactService();
		if(remoteInt!=null)
			return;
		try {
			remoteInt=con.getRemote();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * start the service
	 */
	public void startListen() {
		System.out.println("start listening");
		try {
			remoteInt.startSync();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	/**
	 * stop the service
	 */
	public void stopListen() {
		System.out.println("stop listening");
		try {
			remoteInt.stopSync();
		}catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	/**
	 * add new folder to the application
	 * @param newFolderName new folder name, null in case of exists folder
	 * @param emails the email addresses of the users we want to share
	 * @param selectedFolders  the folder we want to share, null in case of new folder
	 * @return true in success false otherwise
	 */
	public boolean addNewFolder(String newFolderName, ArrayList<String> emails, ArrayList<String> selectedFolders) {
		//new folder to share
		if(selectedFolders==null){
			System.out.println("share new folder in home network");
			Set<String> boxes=UserInfo.getInstance().getBoxesList();
			//check if the folder name is already in use
			for(String str : boxes)
				if(str.compareTo(newFolderName)==0){
					System.out.println("folder exist!!!");
					return false;
				}
					
			try{
				remoteInt.createNewBox(newFolderName);
				UserInfo.getInstance().addBox(newFolderName);
			}catch(RemoteException e){}
			
		}
		//share exist folder
		else{
			System.out.println("update those folders:");
			for(int i=0; i<selectedFolders.size();i++)
				System.out.println("folder " + i +": " + selectedFolders.get(i));
			}
		//share folder with other clients
		if(emails != null){
			System.out.println("with those members:");	
			for(int i=0; i<emails.size();i++)
				System.out.println("email " + i +": " + emails.get(i));
			try{
				//share exist folders
				if(selectedFolders!=null){
					for(String str : selectedFolders){
						remoteInt.shareBox(emails,str);
					}
				}
				//share new folder
				else{
					remoteInt.shareBox(emails,newFolderName);
					UserInfo.getInstance().addBox(newFolderName);
				}
			}catch(RemoteException e){}
			
		}
		return true;
		
	}
	/**
	 * add new tag algorithm to the application
	 * @param path the path where the class file of the algorithm sits
	 * @return list of the tag type in the beginning and the labels option in rest of the list
	 */
	public ArrayList<String> addPlugIn(String path) {
		int i=path.lastIndexOf("\\");
		String className=path.substring(i+1);
		String onlyPath=path.substring(0, i);
		System.out.println("add new plugin in:"+ onlyPath +" name: "+className);
		ArrayList<String> tagList=null;
		try {
			tagList=remoteInt.addPlugin(onlyPath,className);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return tagList;
		
	}
	/**
	 * search in all shared folders by tags
	 * @param tag we want to find
	 * @param tagTypeList the tag type of the tag
	 * @return tuples that return from the search 
	 */
	public ArrayList<SearchTuple> searchInDB(String tag, ArrayList<String> tagTypeList) {
		System.out.println("search in database for tag: "+ tag + " in category: " + tagTypeList);
		ArrayList<SearchTuple> ret=null;
		try {
			ret=remoteInt.search(tag, tagTypeList);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}

	
	/**
	 * @return all of the client shared folders
	 */
	public Set<String> getFolders() {
		//return UserInfo.getInstance().getBoxesList(); 
		Set<String> ret = null;
		try {
			ret = remoteInt.getBoxesList();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}
	/**
	 * pass all client information to the remote
	 * @return 
	 */
	public ArrayList<ArrayList<String>> getInfo() {
		openRemotInt();
		try{
			UserInfo inf=UserInfo.getInstance();
			inf.setUserName(remoteInt.getUserName());
			inf.setPass(remoteInt.getPass());
			Set<String> tempSet=remoteInt.getBoxesList();
			System.out.println("tempSet "+tempSet.size());
			inf.setBoxesList(tempSet);
			inf.setEmail(remoteInt.getEmail());		
			return remoteInt.getPlugins();
		} catch (RemoteException e) {
			e.printStackTrace();
		}		
		return null;
	}
	/**
	 * link to CleverDropBox web site
	 */
	public void goToWeb() {
		System.out.println("go to web...\n");
		try {
			Desktop.getDesktop().browse(new URI("http://localhost/"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	/**
	 * open file that is in one of the shared folders
	 * @param path the location of the file
	 */
	public void openFile(String path) {
		try {
			remoteInt.openFile(path);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	/**
	 * advanced search in the shared folders
	 * @param tags list of tags to search
	 * @return the search results
	 */
	public ArrayList<SearchTuple> advancedSearch(ArrayList<String> tags) {
		System.out.println("Model : Advanced Search");
		ArrayList<SearchTuple> tuples=null;
		try {
			tuples=remoteInt.advencedSearch(tags);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return tuples; 
		
	}
	/**
	 * change the tag algorithm to use when the application is tag files
	 * @param tagTypes the list of algorithm to use for taging
	 */
	public void changeTagAlgoValid(ArrayList<String> tagTypes) {
		System.out.println("Model : changeTagAlgoValid");
		try {
			remoteInt.changeTagAlgoValid(tagTypes);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
	public void setDbSettings(String dbUserName, String dbPassword) {
		System.out.println("Model : setDbSettings");
		/*try {
			remoteInt.setDbSettings(dbUserName,dbPassword);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} */
		
	}
	
}
